# -*- coding: utf-8 -*-


from collections.abc import MutableMapping
from datetime import datetime


class Entity(MutableMapping):

    def __setitem__(self, key, value):
        return self.__dict__.__setitem__(key, value)

    def __delitem__(self, key):
        return

    def __getitem__(self, key):
        return self.__dict__.__getitem__(key)

    def __iter__(self):
        return iter(self.__dict__)

    def __len__(self):
        return len(self.__dict__)

    def __str__(self):
        return str(self.__dict__)

    def __repr__(self):
        return '{}, D({})'.format(super(Entity, self).__repr__(),
                                  self.__dict__)
    # def __getattr__(self, item):
    #     if hasattr(self,item):
    #         return


class TickEntity(Entity):
    def __init__(self):
        """初始化"""
        '''合约'''
        self.Instrument = ''
        '''合约'''
        self.InstrumentID = ''
        self.ExchangeID = ''
        '''最新价'''
        self.LastPrice = 0.0
        '''最新价'''
        '''挂卖价'''
        self.AskPrice1 = 0.0
        '''挂卖价'''
        '''挂买价'''
        self.BidPrice1 = 0.0
        '''挂买价'''
        '''挂卖量'''
        self.AskVolume1 = 0
        '''挂卖量'''
        '''挂买量'''
        self.BidVolume1 = 0
        '''挂买量'''
        '''时间'''
        self.UpdateTime = ''
        '''时间'''
        '''毫秒'''
        self.UpdateMillisec = 0
        '''毫秒'''
        '''成交量'''
        self.Volume = 0
        '''成交量'''
        '''持仓量'''
        self.OpenInterest = 1.0
        '''持仓量'''
        '''均价'''
        self.AveragePrice = 0.0
        '''均价'''
        '''涨板价'''
        self.UpperLimitPrice = 0.0
        '''涨板价'''
        '''跌板价'''
        self.LowerLimitPrice = 0.0
        '''跌板价'''
        '''昨结算价'''
        self.PreSettlementPrice = 0.0
        '''昨结算价'''
        '''昨日持仓'''
        self.PreOpenInterest = 0.0
        '''当日最高价'''
        self.HighestPrice = 0.0
        '''当日最低价'''
        self.LowestPrice = 0.0
        '''当日开盘价'''
        self.OpenPrice = 0.0
        '''当日收盘价'''
        self.ClosePrice = 0.0
        '''昨日收盘价'''
        self.PreClosePrice = 0.0
        '''日期时间'''
        self.DateTime = ''
        self.SettlementPrice = 0.0
        self.AskPrice2 = 0.0
        self.BidPrice2 = 0.0
        self.AskVolume2 = 0
        self.BidVolume2 = 0
        self.AskPrice3 = 0.0
        self.BidPrice3 = 0.0
        self.AskVolume3 = 0
        self.BidVolume3 = 0
        self.AskPrice4 = 0.0
        self.BidPrice4 = 0.0
        self.AskVolume4 = 0
        self.BidVolume4 = 0
        self.AskPrice5 = 0.0
        self.BidPrice5 = 0.0
        self.AskVolume5 = 0
        self.BidVolume5 = 0
        self.AskPrice = 0.
        self.BidPrice = 0.
        self.AskVolume = 0
        self.BidVolume = 0
        self.TradingDay = ''
        self.ActionDay = ''
        self.RcvTime = ''


class BarEntity(Entity):
    def __init__(self):
        self.symbol: str = ''
        self.exchange: str = ''
        self.datetime = ''

        self.interval = 0
        self.volume: int = 0
        self.open_interest: int = 0
        self.open_price: float = 0
        self.high_price: float = 0
        self.low_price: float = 0
        self.close_price: float = 0
        self.actionday: str = ''
        self.tradingday: str = ''

    @property
    def Open(self):
        return self.open_price

    @property
    def High(self):
        return self.high_price

    @property
    def Low(self):
        return self.low_price

    @property
    def Close(self):
        return self.close_price

    @property
    def Date(self):
        return self.datetime

    @property
    def Instrument(self):
        return self.symbol

    @property
    def open(self):
        return self.open_price

    @property
    def high(self):
        return self.high_price

    @property
    def low(self):
        return self.low_price

    @property
    def close(self):
        return self.close_price

    @property
    def Volume(self):
        return self.volume

    @property
    def openinterest(self):
        return self.open_interest


class AccEntity(Entity):
    """资金账户"""

    def __init__(self):
        self.BrokerID: str = ''
        self.AccountID: str = ''
        self.PreMortgage: float = 0.0
        self.PreCredit: float = 0.0
        self.PreDeposit: float = 0.0
        self.PreBalance: float = 0.0
        self.PreMargin: float = 0.0
        self.InterestBase: float = 0.0
        self.Interest: float = 0.0
        self.Deposit: float = 0.0
        self.Withdraw: float = 0.0
        self.FrozenMargin: float = 0.0
        self.FrozenCash: float = 0.0
        self.FrozenCommission: float = 0.0
        self.CurrMargin: float = 0.0
        self.CashIn: float = 0.0
        self.Commission: float = 0.0
        self.CloseProfit: float = 0.0
        self.PositionProfit: float = 0.0
        self.Balance: float = 0.0
        self.Available: float = 0.0
        self.WithdrawQuota: float = 0.0
        self.Reserve: float = 0.0
        self.TradingDay: str = ''
        self.SettlementID: int = 0
        self.Credit: float = 0.0
        self.Mortgage: float = 0.0
        self.ExchangeMargin: float = 0.0
        self.DeliveryMargin: float = 0.0
        self.ExchangeDeliveryMargin: float = 0.0
        self.ReserveBalance: float = 0.0
        self.CurrencyID: str = ''
        self.PreFundMortgageIn: float = 0.0
        self.PreFundMortgageOut: float = 0.0
        self.FundMortgageIn: float = 0.0
        self.FundMortgageOut: float = 0.0
        self.FundMortgageAvailable: float = 0.0
        self.MortgageableFund: float = 0.0
        self.SpecProductMargin: float = 0.0
        self.SpecProductFrozenMargin: float = 0.0
        self.SpecProductCommission: float = 0.0
        self.SpecProductFrozenCommission: float = 0.0
        self.SpecProductPositionProfit: float = 0.0
        self.SpecProductCloseProfit: float = 0.0
        self.SpecProductPositionProfitByAlg: float = 0.0
        self.SpecProductExchangeMargin: float = 0.0
        self.BizType: str = ''
        self.FrozenSwap: float = 0.0
        self.RemainSwap: float = 0.0


class InstrumentEntity(Entity):
    """合约"""

    def __init__(self):
        self.InstrumentID: str = ''
        self.ExchangeID: str = ''
        self.InstrumentName: str = ''
        self.ExchangeInstID: str = ''
        self.ProductID: str = ''
        self.ProductClass: str = ''
        self.DeliveryYear: int = 0
        self.DeliveryMonth: int = 0
        self.MaxMarketOrderVolume: int = 0
        self.MinMarketOrderVolume: int = 0
        self.MaxLimitOrderVolume: int = 0
        self.MinLimitOrderVolume: int = 0
        self.VolumeMultiple: int = 0
        self.PriceTick: float = 0.0
        self.CreateDate: str = ''
        self.OpenDate: str = ''
        self.ExpireDate: str = ''
        self.StartDelivDate: str = ''
        self.EndDelivDate: str = ''
        self.InstLifePhase: str = ''
        self.IsTrading: int = 0
        self.PositionType: str = ''
        self.PositionDateType: str = ''
        self.LongMarginRatio: float = 0.0
        self.ShortMarginRatio: float = 0.0
        self.MaxMarginSideAlgorithm: str = ''
        self.UnderlyingInstrID: str = ''
        self.StrikePrice: float = 0.0
        self.OptionsType: str = ''
        self.UnderlyingMultiple: float = 0.0
        self.CombinationType: str = ''


class InstrumentMarginRateEntity(Entity):
    """合约保证金率"""

    def __init__(self):
        self.InstrumentID: str = ''
        self.InvestorRange: str = ''
        self.BrokerID: str = ''
        self.InvestorID: str = ''
        self.HedgeFlag: str = ''
        self.LongMarginRatioByMoney: float = 0.0
        self.LongMarginRatioByVolume: float = 0.0
        self.ShortMarginRatioByMoney: float = 0.0
        self.ShortMarginRatioByVolume: float = 0.0
        self.IsRelative: int = 0
        self.ExchangeID: str = ''
        self.InvestUnitID: str = ''


class InstrumentCommissionRateEntity(Entity):
    """合约手续费率"""

    def __init__(self):
        self.InstrumentID: str = ''
        self.InvestorRange: str = ''
        self.BrokerID: str = ''
        self.InvestorID: str = ''
        self.OpenRatioByMoney: float = 0.0
        self.OpenRatioByVolume: float = 0.0
        self.CloseRatioByMoney: float = 0.0
        self.CloseRatioByVolume: float = 0.0
        self.CloseTodayRatioByMoney: float = 0.0
        self.CloseTodayRatioByVolume: float = 0.0
        self.ExchangeID: str = ''
        self.BizType: str = ''
        self.InvestUnitID: str = ''


class InvestorPositionEntity(Entity):
    """投资者持仓"""

    def __init__(self):
        self.InstrumentID: str = ''
        self.BrokerID: str = ''
        self.InvestorID: str = ''
        self.PosiDirection: str = ''
        self.HedgeFlag: str = ''
        self.PositionDate: str = ''
        self.YdPosition: int = 0
        self.Position: int = 0
        self.LongFrozen: int = 0
        self.ShortFrozen: int = 0
        self.LongFrozenAmount: float = 0.0
        self.ShortFrozenAmount: float = 0.0
        self.OpenVolume: int = 0
        self.CloseVolume: int = 0
        self.OpenAmount: float = 0.0
        self.CloseAmount: float = 0.0
        self.PositionCost: float = 0.0
        self.PreMargin: float = 0.0
        self.UseMargin: float = 0.0
        self.FrozenMargin: float = 0.0
        self.FrozenCash: float = 0.0
        self.FrozenCommission: float = 0.0
        self.CashIn: float = 0.0
        self.Commission: float = 0.0
        self.CloseProfit: float = 0.0
        self.PositionProfit: float = 0.0
        self.PreSettlementPrice: float = 0.0
        self.SettlementPrice: float = 0.0
        self.TradingDay: str = ''
        self.SettlementID: int = 0
        self.OpenCost: float = 0.0
        self.ExchangeMargin: float = 0.0
        self.CombPosition: int = 0
        self.CombLongFrozen: int = 0
        self.CombShortFrozen: int = 0
        self.CloseProfitByDate: float = 0.0
        self.CloseProfitByTrade: float = 0.0
        self.TodayPosition: int = 0
        self.MarginRateByMoney: float = 0.0
        self.MarginRateByVolume: float = 0.0
        self.StrikeFrozen: int = 0
        self.StrikeFrozenAmount: float = 0.0
        self.AbandonFrozen: int = 0
        self.ExchangeID: str = ''
        self.YdStrikeFrozen: int = 0
        self.InvestUnitID: str = ''
        self.PositionCostOffset: float = 0.0


class InvestorPositionDetailEntity(Entity):
    """投资者持仓明细"""

    def __init__(self):
        self.InstrumentID: str = ''
        self.BrokerID: str = ''
        self.InvestorID: str = ''
        self.HedgeFlag: str = ''
        self.Direction: str = ''
        self.OpenDate: str = ''
        self.TradeID: str = ''
        self.Volume: int = 0
        self.OpenPrice: float = 0.0
        self.TradingDay: str = ''
        self.SettlementID: int = 0
        self.TradeType: str = ''
        self.CombInstrumentID: str = ''
        self.ExchangeID: str = ''
        self.CloseProfitByDate: float = 0.0
        self.CloseProfitByTrade: float = 0.0
        self.PositionProfitByDate: float = 0.0
        self.PositionProfitByTrade: float = 0.0
        self.Margin: float = 0.0
        self.ExchMargin: float = 0.0
        self.MarginRateByMoney: float = 0.0
        self.MarginRateByVolume: float = 0.0
        self.LastSettlementPrice: float = 0.0
        self.SettlementPrice: float = 0.0
        self.CloseVolume: int = 0
        self.CloseAmount: float = 0.0
        self.TimeFirstVolume: int = 0
        self.InvestUnitID: str = ''


class OrderEntity(Entity):
    """报单"""

    def __init__(self):
        self.BrokerID: str = ''
        self.InvestorID: str = ''
        self.InstrumentID: str = ''
        self.OrderRef: str = ''
        self.UserID: str = ''
        self.OrderPriceType: str = ''
        self.Direction: str = ''
        self.CombOffsetFlag: str = ''
        self.CombHedgeFlag: str = ''
        self.LimitPrice: float = 0.0
        self.VolumeTotalOriginal: int = 0
        self.TimeCondition: str = ''
        self.GTDDate: str = ''
        self.VolumeCondition: str = ''
        self.MinVolume: int = 0
        self.ContingentCondition: str = ''
        self.StopPrice: float = 0.0
        self.ForceCloseReason: str = ''
        self.IsAutoSuspend: int = 0
        self.BusinessUnit: str = ''
        self.RequestID: int = 0
        self.OrderLocalID: str = ''
        self.ExchangeID: str = ''
        self.ParticipantID: str = ''
        self.ClientID: str = ''
        self.ExchangeInstID: str = ''
        self.TraderID: str = ''
        self.InstallID: int = 0
        self.OrderSubmitStatus: str = ''
        self.NotifySequence: int = 0
        self.TradingDay: str = ''
        self.SettlementID: int = 0
        self.OrderSysID: str = ''
        self.OrderSource: str = ''
        self.OrderStatus: str = ''
        self.OrderType: str = ''
        self.VolumeTraded: int = 0
        self.VolumeTotal: int = 0
        self.InsertDate: str = ''
        self.InsertTime: str = ''
        self.ActiveTime: str = ''
        self.SuspendTime: str = ''
        self.UpdateTime: str = ''
        self.CancelTime: str = ''
        self.ActiveTraderID: str = ''
        self.ClearingPartID: str = ''
        self.SequenceNo: int = 0
        self.FrontID: int = 0
        self.SessionID: int = 0
        self.UserProductInfo: str = ''
        self.StatusMsg: str = ''
        self.UserForceClose: int = 0
        self.ActiveUserID: str = ''
        self.BrokerOrderSeq: int = 0
        self.RelativeOrderSysID: str = ''
        self.ZCETotalTradedVolume: int = 0
        self.IsSwapOrder: int = 0
        self.BranchID: str = ''
        self.InvestUnitID: str = ''
        self.AccountID: str = ''
        self.CurrencyID: str = ''
        self.IPAddress: str = ''
        self.MacAddress: str = ''


class TradeEntity(Entity):
    """成交"""

    def __init__(self):
        self.BrokerID: str = ''
        self.InvestorID: str = ''
        self.InstrumentID: str = ''
        self.OrderRef: str = ''
        self.UserID: str = ''
        self.ExchangeID: str = ''
        self.TradeID: str = ''
        self.Direction: str = ''
        self.OrderSysID: str = ''
        self.ParticipantID: str = ''
        self.ClientID: str = ''
        self.TradingRole: str = ''
        self.ExchangeInstID: str = ''
        self.OffsetFlag: str = ''
        self.HedgeFlag: str = ''
        self.Price: float = 0.0
        self.Volume: int = 0
        self.TradeDate: str = ''
        self.TradeTime: str = ''
        self.TradeType: str = ''
        self.PriceSource: str = ''
        self.TraderID: str = ''
        self.OrderLocalID: str = ''
        self.ClearingPartID: str = ''
        self.BusinessUnit: str = ''
        self.SequenceNo: int = 0
        self.TradingDay: str = ''
        self.SettlementID: int = 0
        self.BrokerOrderSeq: int = 0
        self.TradeSource: str = ''
        self.InvestUnitID: str = ''


class InputOrderEntity(Entity):
    """委托"""

    def __init__(self):
        self.instrument = ''
        self.price = 0.0
        self.vol = 0
        self.price_type = ''
        self.direction = ''
        self.offset = ''
        self.dt = datetime.now().strftime('%Y%m%d %H:%M:%S')


class ReqSubQuoteEntity(Entity):
    """订阅或者查询行情的请求"""

    def __int__(self):
        self.symbol = ''
        self.exchange = ''
        self.startDt = ''  # yyyy-mm-dd hh:mm:ss
        self.endDt = ''  # yyyy-mm-dd hh:mm:ss
        self.period = 0  # 周期类型，
